package question07;

/**
 * @author yuan
 * @date 2021/12/14
 */

/**
 * 题目：
 *      将有符号数数字反转
 * 思路：
 *      1、首先不管是正数还是负数，如果绝对值都小于 10，反转后都为本身
 *      2、将每个数字的最低位 firstNum 依次弹出，用变量 reverseValue 用于接收，
 *      reverseValue = reverseValue * 10 + firstNum，进行 * 10 推入，
 *      就可以实现翻转操作
 *      3、接收的时候先进行 int 越界校验，正数的可能越界情况，因为即将进行的 *10 操作，
 *      所以当 reverseValue > Integer.MAX_VALUE / 10 越界 或 reverseValue 与 int 最大值
 *      的十分之一相等并且 firstNum > int 最大值的个位数时越界，即
 *      reverseValue == Integer.MAX_VALUE / 10 && firstNum > Integer.MAX_VALUE % 10
 *      负数同理
 */
public class Solution {
    public static void main(String[] args) {
        // System.out.println(new Solution().reverse(123));
        // System.out.println(new Solution().reverse(-123));
        System.out.println(new Solution().reverse(120));
        // System.out.println(new Solution().reverse(0));
        // System.out.println(new Solution().reverse(-2147483648));
    }

    /**
     * 将有符号数数字反转
     * @param x
     * @return
     */
    public int reverse(int x) {

        // 如果为个位数，直接返回自己
        if (x / 10 == 0) return x;
        int reverseValue = 0;
        while (x != 0) {
            // 弹出
            int firstNum = x % 10;
            x /= 10;
            // 有符号数范围判断
            // 因为即将进行乘 10 操作，所以比较 int 的最大值和最小值除以 10
            // 正数校验
            if (reverseValue  > Integer.MAX_VALUE / 10
                    || reverseValue == Integer.MAX_VALUE / 10 &&
                        firstNum > Integer.MAX_VALUE % 10) return 0;
            // 负数校验
            if (reverseValue  < Integer.MIN_VALUE / 10
                    || reverseValue == Integer.MIN_VALUE / 10 &&
                        firstNum < Integer.MIN_VALUE % 10) return 0;
            // 推入
            reverseValue = reverseValue * 10 + firstNum;
        }
        return reverseValue;
    }
}
